package com.ddm.controller.wxadmin;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ddm.constant.MessageConstant;
import com.ddm.constant.VXConstant;
import com.ddm.dto.page.PageQueryDTO;
import com.ddm.dto.vxDTO.ExamDTO;
import com.ddm.dto.vxDTO.QuestionDTO;
import com.ddm.entity.vxEntity.Exam;
import com.ddm.entity.vxEntity.ExamQuestion;
import com.ddm.exception.DataErrorException;
import com.ddm.result.PageResult;
import com.ddm.result.Result;
import com.ddm.service.vxService.ExamQuestionService;
import com.ddm.service.vxService.ExamService;
import com.ddm.utils.BeanCopyUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import com.ddm.vo.vxVo.ExamVO;
import com.ddm.vo.vxVo.PrizeResultVO;
import com.ddm.vo.vxVo.PrizeStatisticsVO;
import com.ddm.service.vxService.PrizeCalculationService;
import java.math.BigDecimal;

/**
 * @author horizon
 * @since 2025-01-17
 */
@RestController
@RequestMapping("/admin/exam")
@Slf4j
@Api("考试接口")
public class ExamController {

    @Autowired
    ExamService examService;
    @Autowired
    ExamQuestionService examQuestionService;
    @Autowired
    PrizeCalculationService prizeCalculationService;

    @PostMapping
    @ApiOperation("添加考试")
    public Result<String> addExam(@RequestBody ExamDTO examDTO){
        log.info("添加考试");
        if (examDTO.getExamName()==null || examDTO.getQuestionList()==null){
            throw new DataErrorException(MessageConstant.NULL_DATA);
        }

        return Result.success( examService.addExam(examDTO));
    }

    @DeleteMapping("/{id}")
    @ApiOperation("根据id删除考试")
    public Result<String> deleteQuestion(@PathVariable Long id ){
        log.info("根据id删除考试:{}",id);
        LambdaQueryWrapper<ExamQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExamQuestion::getExamId , id);
        examQuestionService.remove(wrapper);
        examService.removeById(id);
        return Result.success("删除成功");
    }

    @PutMapping("/{id}")
    @ApiOperation("根据id修改考试")
    public Result updateExam(@RequestBody ExamDTO examDTO,@PathVariable Long id){
        log.info("修改考试:{}:",examDTO.getExamName());
        if (examService.getById(id) ==null){
            throw new DataErrorException(MessageConstant.ERROR_DATA);
        }
        
        // 验证考试限时
        Integer duration = examDTO.getDuration();
        if (duration != null && (duration < VXConstant.MIN_EXAM_DURATION || duration > VXConstant.MAX_EXAM_DURATION)) {
            throw new DataErrorException("考试限时必须在" + VXConstant.MIN_EXAM_DURATION + "-" + VXConstant.MAX_EXAM_DURATION + "分钟之间");
        }
        
        // 验证获奖比例
        validatePrizeRatios(examDTO);
        
        Exam exam = BeanCopyUtil.BeanCopy(examDTO, Exam.class);
        exam.setId(id);
        examService.updateById(exam);
        //修改关联表
        List<QuestionDTO> questionList = examDTO.getQuestionList();
        examQuestionService.remove(new LambdaQueryWrapper<ExamQuestion>().eq(ExamQuestion::getExamId,id));
        ExamQuestion examQuestion = new ExamQuestion();
        for (QuestionDTO questionDTO : questionList) {
            examQuestion.setExamId(id);
            examQuestion.setQuestionId(questionDTO.getId());
            examQuestionService.save(examQuestion);
        }
        return Result.success("修改成功");

    }

    @GetMapping
    @ApiOperation("分页查询考试")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    public Result<PageResult> getExamList( PageQueryDTO pageQueryDTO){
        log.info("分页查询考试");
        return Result.success(examService.getExamList(pageQueryDTO));
    }

    @GetMapping("/{id}")
    @ApiOperation("根据考试ID查询考试详情（包含问题列表）")
    public Result<ExamVO> getExamDetail(@PathVariable Long id){
        log.info("根据考试ID查询考试详情:{}", id);
        if (id == null){
            throw new DataErrorException(MessageConstant.NULL_DATA);
        }
        return Result.success(examService.getExamDetail(id));
    }

    @GetMapping("/{examId}/prizes")
    @ApiOperation("获取竞赛获奖名单")
    public Result<List<PrizeResultVO>> getPrizeList(@PathVariable Long examId) {
        log.info("获取竞赛获奖名单，竞赛ID: {}", examId);
        return Result.success(prizeCalculationService.calculatePrizes(examId));
    }

    @GetMapping("/{examId}/prize-statistics")
    @ApiOperation("获取竞赛获奖统计")
    public Result<PrizeStatisticsVO> getPrizeStatistics(@PathVariable Long examId) {
        log.info("获取竞赛获奖统计，竞赛ID: {}", examId);
        return Result.success(prizeCalculationService.getPrizeStatistics(examId));
    }

    /**
     * 验证获奖比例
     * @param examDTO 考试DTO
     */
    private void validatePrizeRatios(ExamDTO examDTO) {
        BigDecimal firstRatio = examDTO.getFirstPrizeRatio();
        BigDecimal secondRatio = examDTO.getSecondPrizeRatio();
        BigDecimal thirdRatio = examDTO.getThirdPrizeRatio();
        
        // 如果设置了获奖比例，则进行验证
        if (firstRatio != null || secondRatio != null || thirdRatio != null) {
            // 验证比例范围（0-1之间）
            if (firstRatio != null && (firstRatio.compareTo(BigDecimal.ZERO) < 0 || firstRatio.compareTo(BigDecimal.ONE) > 0)) {
                throw new DataErrorException("一等奖比例必须在0-1之间");
            }
            if (secondRatio != null && (secondRatio.compareTo(BigDecimal.ZERO) < 0 || secondRatio.compareTo(BigDecimal.ONE) > 0)) {
                throw new DataErrorException("二等奖比例必须在0-1之间");
            }
            if (thirdRatio != null && (thirdRatio.compareTo(BigDecimal.ZERO) < 0 || thirdRatio.compareTo(BigDecimal.ONE) > 0)) {
                throw new DataErrorException("三等奖比例必须在0-1之间");
            }
            
            // 验证总比例不超过100%
            BigDecimal totalRatio = BigDecimal.ZERO;
            if (firstRatio != null) totalRatio = totalRatio.add(firstRatio);
            if (secondRatio != null) totalRatio = totalRatio.add(secondRatio);
            if (thirdRatio != null) totalRatio = totalRatio.add(thirdRatio);
            
            if (totalRatio.compareTo(BigDecimal.ONE) > 0) {
                throw new DataErrorException("获奖比例总和不能超过100%");
            }
        }
    }

}

